/* STANDARD LIBRARY */
#include<cstdio>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<math.h>

/* ADDITIONAL LIBRARY */
#include"constants.h" // constants
#include"supToGSL.h" // support to GSL library
#include"supToMain.h" // supprot to main program (additional functions)
#include"setOfFuns.h" // set of functions to solve using GSL
#include"colorText.h" // functions which change color of text (for fun)
#include"Gmros.h" // Java Native Interface head
using namespace std;


jdoubleArray jOnePoint(JNIEnv *env, jobject jobj, jdoubleArray _par, jdoubleArray _x, functionF _f)
{
	if(DEBUG) { printf("Start native metod: jOnePoint\n"); }

	// Initialization
	jboolean isCopyPar, isCopyX, isCopyY;
	jdouble* jpar = env->GetDoubleArrayElements(_par, &isCopyPar);
	jdouble* jx = env->GetDoubleArrayElements(_x, &isCopyX);
	jint jparLength = env->GetArrayLength(_par);
	jint jxLength = env->GetArrayLength(_x);
	jdoubleArray jyA = env->NewDoubleArray(jxLength);
	jdouble* jy = env->GetDoubleArrayElements(jyA, &isCopyY);

	// Solving
	MultirootSolverF S(_f, jxLength);
	Parameters *Par = new Parameters(jparLength, jpar);
	Parameters *X0 = new Parameters(jxLength, jx);
	S.solveFor(Par, X0);
	Parameters *Y = S.getResult();
	
	// Cleaning
	delete Par;
	delete X0;
	if (isCopyPar == JNI_TRUE) {
		env->ReleaseDoubleArrayElements(_par, jpar, JNI_ABORT);
	}
	if (isCopyX == JNI_TRUE) {
		env->ReleaseDoubleArrayElements(_x, jx, JNI_ABORT);
	}

	// RETURNING
	if(Y == NULL) { printf("Returning NULL \n"); return NULL; }
	
	Y->print();
	for(jint i=0; i<jxLength; i++) { jy[i] = (*Y)[i]; }

	delete Y;
	if (isCopyY == JNI_TRUE) {
		env->ReleaseDoubleArrayElements(jyA, jy, 0);
	}

	return jyA;
}

JNIEXPORT jdoubleArray JNICALL Java_Gmros_jOnePointGA (JNIEnv *env, jobject jobj, jdoubleArray _par, jdoubleArray _x)
{
	return jOnePoint(env, jobj, _par, _x, &jkGA);
}

JNIEXPORT jdoubleArray JNICALL Java_Gmros_jOnePointSGA (JNIEnv *env, jobject jobj, jdoubleArray _par, jdoubleArray _x)
{
	return jOnePoint(env, jobj, _par, _x, &jkSGA);
}
